#include "Controller.hpp"
#include "MenuEvents.hpp"
#include "MeshAlgorithm.hpp"
#include "MeshLoader.hpp"
#include "MeshView.hpp"
#include "MeshView.hpp"
#include "ObjFile.hpp"
#include "PolFile.hpp"
#include "Panel.hpp"
#include "SubdivisionAlgorithm.hpp"
#include "Registration.hpp"
#include "SubFile.hpp"
#include "TetGen.hpp"
#include <iostream>
#include "ViewScene.hpp"
#include <boost/lexical_cast.hpp>
#include <FL/fl_ask.H>
#include "VertexSelector.hpp"
#include "ControlPoint.hpp"

using namespace std;
using namespace boost;
MenuEvents MEvents;

MenuEvents::MenuEvents()
{
   for (int i = 0; i < 16; ++i)
   {
      unsigned col = fl_rgb_color(MeshDraw::sMaterialColors[i][0]*255, MeshDraw::sMaterialColors[i][1]*255, MeshDraw::sMaterialColors[i][2]*255);
      Fl::set_color((Fl_Color)(FL_FREE_COLOR + i), col);
   }
}

// Most commands get processed here:
void MenuEvents::Handle(std::string  aCommand,
                        boost::many& aArgs)
{
   bool handled = DoSignals(aCommand, aArgs);
   if (! handled)
   {
      handled = true;
      if (aCommand == "Load Mesh")
      {
         handled=true;
         MeshView* meshPtr = new MeshView;
         MeshLoader::Load(*meshPtr, any_cast<string>(aArgs[0]));
         ViewScene::GetInstance().AddMesh(meshPtr);
         Controller::GetInstance().RedrawGl();
      }
      else if (aCommand == "Mesh Added")
      {
         Controller::GetInstance().mMeshPanel->mMeshes->UpdateRows();
         MEvents("Mesh Selected");
         MEvents("Redraw");
      }
      else if (aCommand == "Mesh List Updated")
      {
         Controller::GetInstance().mMeshPanel->mMeshes->UpdateRows();
      }
      else if (aCommand == "Mesh Selected")
      {
         MeshView* m = ViewScene::GetInstance().GetSelectedMesh();
         Controller::GetInstance().mMeshPanel->mMeshes->UpdateSelected();
         if (m != 0)
         {
            LoadMeshConfig();
         }
      }
      else if (aCommand == "Redraw")
      {
         Controller::GetInstance().RedrawGl();
      }
      else if (aCommand == "Update Mesh Config")
      {
         PullMeshConfig();
      }
      else if (aCommand == "Set Shown Sections")
      {
         PullMeshConfig();
      }
      else if (aCommand == "All Sections")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            //ViewPanel* view = Controller::GetInstance().mViewPanel;
            bool subdivOption = Controller::GetInstance().mViewPanel->mSubdivOption->value() != 0;
            if (subdivOption)
            {
               mesh = mesh->GetSubdivisionMesh();
            }
            MeshViewConfig newConfig = mesh->GetConfig();
            if (newConfig.mHiddenRegions.empty())
            {
               newConfig.mHiddenRegions = mesh->GetRegions();
            }
            else
            {
               newConfig.mHiddenRegions.clear();
            }
            mesh->SetConfig(newConfig, subdivOption);
            (*this)("Mesh Selected");
            Controller::GetInstance().RedrawGl();
         }
      }
      else if (aCommand == "Subdivide Mesh")
      {
         //std::vector<MeshView*>& models = ViewScene::GetInstance().mModels;
         //Fl_Browser* mlist = Controller::GetInstance().mMeshPanel->mMeshList;
         //int sel = mlist->value() - 1;
         //if (sel >= 0 && sel < models.size())
         //{
         //   MeshView* newmesh = new MeshView;
         //   newmesh->mMesh.clone(models[sel]->mMesh);
         //   SubdivisionAlgorithm::SubdivideMesh(newmesh->mMesh, 1);
         //   newmesh->UpdateMesh();
         //   newmesh->mName = models[sel]->mName + "-subdiv";
         //   ViewScene::GetInstance().AddMesh(newmesh);
         //}
      }
      else if (aCommand == "Subdiv Mesh Options"
         || aCommand == "Base Mesh Options")
      {
         LoadMeshConfig();
      }
      else if (aCommand == "Move Mesh")
      {
         ViewScene::GetInstance().MoveMesh(ViewScene::GetInstance().GetSelectedMesh(), boost::any_cast<int>(aArgs[0]));
         (*this)("Mesh Added");
         Controller::GetInstance().RedrawGl();
      }
      else if (aCommand == "Mesh Properties")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (aArgs.size() > 0)
         {
            mesh = any_cast<MeshView*>(aArgs[0]);
         }
         if (mesh)
         {
            ViewScene::GetInstance().SetSelectedMesh(mesh);
            std::string properties;
            properties += "Mesh '" + mesh->mName + "':";
            properties += "\nVertices: " + boost::lexical_cast<std::string>(mesh->mMesh.verts.size());
            properties += "\nCrease Faces: " + boost::lexical_cast<std::string>(mesh->mMesh.crease_faces.size());
            properties += "\nCrease Edges: " + boost::lexical_cast<std::string>(mesh->mMesh.crease_edges.size());
            properties += "\nPolys: " + boost::lexical_cast<std::string>(mesh->mMesh.polys.size());
            Controller::GetInstance().mPropertiesDlg->mName->value(mesh->mName.c_str());
            Controller::GetInstance().mPropertiesDlg->mMeshInfo->value(properties.c_str());
            Controller::GetInstance().mPropertiesDlg->mWindow->show();
         }
      }
      else if (aCommand == "Properties OK")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         meshPtr->mName = Controller::GetInstance().mPropertiesDlg->mName->value();
         MEvents("Mesh List Updated");
         Controller::GetInstance().mPropertiesDlg->mWindow->hide();
      }
      else if (aCommand == "Set Subdivision Level")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            int lvl = boost::any_cast<int>(aArgs[0]);
            mesh->SetSubdivision(lvl);
            MEvents("Redraw");
         }
      }
      else if (aCommand == "Remove Mesh")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (aArgs.size() > 0)
         {
            meshPtr = any_cast<MeshView*>(aArgs[0]);
         }
         ViewScene::GetInstance().Remove(meshPtr);
         delete meshPtr;
         Controller::GetInstance().mMeshPanel->mMeshes->UpdateRows();
      }
      else if (aCommand == "Simplify Surface")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            std::string properties;
            properties += "Mesh '" + mesh->mName + "':";
            properties += "\nVertices: " + boost::lexical_cast<std::string>(mesh->mMesh.verts.size());
            properties += "\nCrease Faces: " + boost::lexical_cast<std::string>(mesh->mMesh.crease_faces.size());
            properties += "\nCrease Edges: " + boost::lexical_cast<std::string>(mesh->mMesh.crease_edges.size());
            properties += "\nPolys: " + boost::lexical_cast<std::string>(mesh->mMesh.polys.size());
            Controller::GetInstance().mSimplifyDlg->mMeshInfo->value(properties.c_str());
            Controller::GetInstance().mSimplifyDlg->mFaceCount->value(boost::lexical_cast<std::string>(mesh->mMesh.crease_faces.size()).c_str());
            Controller::GetInstance().mSimplifyDlg->mWindow->show();
         }
      }
      else if (aCommand == "Simplify Surface OK")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            int newFaces = boost::lexical_cast<int>(Controller::GetInstance().mSimplifyDlg->mFaceCount->value());
            Controller::GetInstance().mSimplifyDlg->mWindow->hide();
            ObjFile::Write("tmp_qs_in.obj", mesh->mMesh.GetCreaseMesh(), true);
            stringstream ss; 
            ss << "QSlim.exe -t " << newFaces << " -o tmp_qs_out.obj tmp_qs_in.obj";
            system(ss.str().c_str());
            MeshView* newMesh = new MeshView;
            newMesh->mName = mesh->mName + "-Simp";
            ObjFile::Read("tmp_qs_out.obj", newMesh->mMesh.GetCreaseMesh());
            newMesh->UpdateMesh();
            ViewScene::GetInstance().AddMesh(newMesh);
         }
      }
      else if (aCommand == "Save Sub")
      {
         PolyMesh* meshPtr = 0;
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            bool subdivOption = Controller::GetInstance().mViewPanel->mSubdivOption->value() != 0;
            if (subdivOption)
            {
               if (mesh->GetSubdivisionMesh() != 0)
               {
                  meshPtr = &mesh->GetSubdivisionMesh()->mMesh;
               }
            }
            else
            {
               meshPtr = &mesh->mMesh;
            }
            if (meshPtr != 0)
            {
               const char* strBack = fl_file_chooser("Write Mesh to .sub file","*.sub",".");
               if(strBack)
               {
                  SubFile::Write(strBack, *meshPtr);
               }
            }
         }
      }
      else if (aCommand == "Save Obj")
      {
         Mesh* meshPtr = 0;
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            bool subdivOption = Controller::GetInstance().mViewPanel->mSubdivOption->value() != 0;
            if (subdivOption)
            {
               if (mesh->GetSubdivisionMesh() != 0)
               {
                  meshPtr = &mesh->GetSubdivisionMesh()->mMesh.GetCreaseMesh();
               }
            }
            else
            {
               meshPtr = &mesh->mMesh.GetCreaseMesh();
            }
            if (meshPtr != 0)
            {
               const char* strBack = fl_file_chooser("Write Mesh to .obj file","*.obj",".");
               if(strBack)
               {
                  ObjFile::Write(strBack, *meshPtr);
               }
            }
         }
      }
      else if (aCommand == "Save Pol")
      {
         PolyMesh* meshPtr = 0;
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            bool subdivOption = Controller::GetInstance().mViewPanel->mSubdivOption->value() != 0;
            if (subdivOption)
            {
               if (mesh->GetSubdivisionMesh() != 0)
               {
                  meshPtr = &mesh->GetSubdivisionMesh()->mMesh;
               }
            }
            else
            {
               meshPtr = &mesh->mMesh;
            }
            if (meshPtr != 0)
            {
               const char* strBack = fl_file_chooser("Write Mesh to .pol file","*.pol",".");
               if(strBack)
               {
                  PolFile::Write(strBack, *meshPtr);
               }
            }
         }
      }
      else if (aCommand == "Tetrahedralize")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            MeshView* newmesh = new MeshView();
            TetGen::Tetrahedralize(mesh->mMesh.GetCreaseMesh(), newmesh->mMesh);
            newmesh->mName = mesh->mName + "-Vol";
            newmesh->mMesh.UpdatePolys();
            newmesh->UpdateMesh();
            ViewScene::GetInstance().AddMesh(newmesh);
         }
      }
      else if (aCommand == "Clean Bad Faces")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            MeshAlgorithm::CleanBadFaces(mesh->mMesh.GetCreaseMesh());
            mesh->Rebuild();
         }
         MEvents("Redraw");
      }
      else if (aCommand == "Materials Apply")
      {
         MeshView* mesh = ViewScene::GetInstance().GetSelectedMesh();
         if (mesh)
         {
            int m1 = 
            boost::lexical_cast<int>(
               Controller::GetInstance().mMaterialDlg->mMaterial1->value());
            int m2 = boost::lexical_cast<int>(
               Controller::GetInstance().mMaterialDlg->mMaterial2->value());
            std::vector<int> faces;
            mesh->GetSelectedFaces(faces);
            for (size_t i = 0; i < faces.size(); ++i)
            {
               Face& f = mesh->mMesh.crease_faces[faces[i]];
               f.materials[0] = m1;
               f.materials[1] = m2;
            }
            mesh->mMesh.UpdateFaces();
            mesh->UpdateMesh();
            MEvents("Mesh Selected");
            MEvents("Redraw");
         }
      }
      else if (aCommand == "Vertex Selection")
      {
         ViewScene::GetInstance().SetSelectionMode(ViewScene::cVERTEX);
      }
      else if (aCommand == "Loop Selection")
      {
         ViewScene::GetInstance().SetSelectionMode(ViewScene::cLOOP);
      }
      else if (aCommand == "Interface Selection")
      {
         ViewScene::GetInstance().SetSelectionMode(ViewScene::cINTERFACE);
      }
      else if (aCommand == "Edge Patch Selection")
      {
         ViewScene::GetInstance().SetSelectionMode(ViewScene::cEDGE_PATCH);
      }
      else if (aCommand == "Face Selection")
      {
         ViewScene::GetInstance().SetSelectionMode(ViewScene::cFACE);
      }
      else if (aCommand == "Register Dlg")
      {
         Controller::GetInstance().mRegisterDlg->mWindow->show();
      }
      else if (aCommand == "Register To Landmarks")
      {
         MeshView* selectedMesh = ViewScene::GetInstance().GetSelectedMesh();
         if (selectedMesh != 0)
         {
            float fitWeight(40), energy(1);
            int iterations(1);
            int sublevel(3);
            if (aArgs.size() == 4)
            {
               fitWeight = any_cast<float>(aArgs[0]);
               energy = any_cast<float>(aArgs[1]);
               iterations = any_cast<int>(aArgs[2]);
               sublevel = any_cast<int>(aArgs[3]);
            }
            //for (int i = 0; i < iterations; ++i)
            Registration::AlignLS2(selectedMesh->mMesh, selectedMesh->mLandmarks, fitWeight, energy, sublevel, iterations);
            selectedMesh->Rebuild();
         }
         MEvents("Redraw");
      }
      else if (aCommand == "Load Landmarks")
      {
         MeshView* selectedMesh = ViewScene::GetInstance().GetSelectedMesh();
         if (selectedMesh != 0)
         {
            const char* strBack = fl_file_chooser("Read Landmarks","*.{suf,obj,gts,off,pol,node,smesh,sub}",GetPanelPath());
            if(strBack)
            {
               MeshView view;
               if (MeshLoader::Load(view, strBack))
               {
                  MeshAlgorithm::ExtractMatPoints(view.mMesh.GetCreaseMesh(), selectedMesh->mLandmarks);
               }
            }
         }
         MEvents("Redraw");
      }
      else if (aCommand == "Prune Hidden Regions")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (meshPtr != 0)
         {
            std::vector<int> keptRegions;
            meshPtr->GetShownRegions(keptRegions);
            MeshAlgorithm::RemoveFaces(meshPtr->mMesh.GetCreaseMesh(), 
               MeshAlgorithm::Inverse(MeshAlgorithm::SelectMaterials(keptRegions.begin(), keptRegions.end())));
            FaceList& faces = *meshPtr->mMesh.crease_faces;
            std::set<int> keptRegionSet(keptRegions.begin(), keptRegions.end());
            for (size_t fi = 0; fi < faces.size(); ++fi)
            {
               Face& f = faces[fi];
               for (int m = 0; m < 2; ++m)
               {
                  if (keptRegionSet.find(f.materials[m]) == keptRegionSet.end())
                  {
                     f.materials[m] = -1;
                  }
               }
            }
            meshPtr->mSelectedVerts.clear();
            meshPtr->Rebuild();
            MEvents("Redraw");
         }
      }
      else if (aCommand == "Detatch Interface")
      {
         MeshView* view = ViewScene::GetInstance().GetSelectedMesh();
         if (view)
         {
            Controller::GetInstance().mInterfaceDetatcher->Begin();
         }
      }
      else if (aCommand == "Delete Selection")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (ViewScene::GetInstance().GetSelectionMode() == ViewScene::cFACE)
         {
            std::vector<int> faces;
            meshPtr->GetSelectedFaces(faces);
            std::sort(faces.begin(), faces.end(), std::greater<int>());
            FaceList& creaseFaces = *meshPtr->mMesh.crease_faces;
            for (size_t i = 0; i < faces.size(); ++i)
            {  
               creaseFaces.erase(creaseFaces.begin() + faces[i]);
            }
            meshPtr->Rebuild();
            MEvents("Redraw");
         }
      }
      else if (aCommand == "Create Face")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (meshPtr != 0 && meshPtr->mSelectedVerts.size() == 3)
         {
            Face f;
            for (int i = 0; i < 3; ++i)
               f.vertex[i] = meshPtr->mSelectedVerts[i];
            f.materials[0] = 0;
            f.materials[1] = 0;
            meshPtr->mMesh.crease_faces.push_back(f);
            meshPtr->Rebuild();
         }
         MEvents("Redraw");
      }
      else if (aCommand == "Select All")
      {
         Controller::GetInstance().mVertexSelector->SelectAll();
         MEvents("Redraw");
      }
      else if (aCommand == "Translate Selection")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (meshPtr != 0)
         {
            Controller::GetInstance().mControlPoint->SetMode(ControlPoint::cTRANSLATE);
         }
      }
      else if (aCommand == "Rotate Selection")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (meshPtr != 0)
         {
            Controller::GetInstance().mControlPoint->SetMode(ControlPoint::cROTATE);
         }
      }
      else if (aCommand == "Scale Selection")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (meshPtr != 0)
         {
            Controller::GetInstance().mControlPoint->SetMode(ControlPoint::cSCALE);
         }
      }
      else if (aCommand == "Change Materials")
      {
         MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
         if (meshPtr != 0)
         {
            if (! meshPtr->GetSelectedFaces().empty())
            {
               Face& f= meshPtr->mMesh.crease_faces[meshPtr->GetSelectedFaces().front()];
               Controller::GetInstance().mMaterialDlg->mMaterial1->value(boost::lexical_cast<std::string>(f.materials[0]).c_str());      
               Controller::GetInstance().mMaterialDlg->mMaterial2->value(boost::lexical_cast<std::string>(f.materials[1]).c_str());      
            }
         }         
         Controller::GetInstance().mMaterialDlg->mWindow->show();
      }
      else
      {
         handled = false;
      }
   }
   // Notify if the command is unprocessed
   if (! handled)
   {
      cout << "Command ignored: " << aCommand << '\n';
   }
}

MenuSignal& MenuEvents::Signal(const std::string& aCommand)
{
   MenuSignal* rv=0;
   SignalMap::iterator i = mSignals.find(aCommand);
   if (i == mSignals.end())
   {
      rv = (mSignals[aCommand] = new MenuSignal);
   }
   else
   {
      rv = i->second;
   }
   return *rv;
}
bool MenuEvents::DoSignals(std::string  aCommand,
                           boost::many& aArgs)
{
   bool handled=false;
   MenuSignal* rv=0;
   SignalMap::iterator i = mSignals.find(aCommand);
   if (i != mSignals.end())
   {
      rv = i->second;
   }
   if (rv)
   {
      if (! rv->empty())
      {
         handled = true;
         (*rv)(aArgs);
      }
   }
   return handled;
}
namespace
{
void SetWidgetValue(Fl_Check_Button* w,
                    bool             aValue)
{
   w->value(aValue ? 1 : 0);
   w->redraw();
}
void SetWidgetValue(Fl_Slider* w,
                    float      aValue)
{
   w->value(aValue);
   w->redraw();
}
void SetWidgetValue(Fl_Counter* w,
                    float      aValue)
{
   w->value(aValue);
   w->redraw();
}

void GetWidgetValue(Fl_Check_Button* w,
                    bool&             aValue)
{
   aValue = w->value() != 0;
}
void GetWidgetValue(Fl_Slider* w,
                    float&      aValue)
{
   aValue = w->value();
}
}
void MenuEvents::LoadMeshConfig()
{
   MeshView* baseMeshPtr = ViewScene::GetInstance().GetSelectedMesh();
   MeshView* m = ViewScene::GetInstance().GetSelectedMesh();
   if (!m) return;
   ViewPanel* view = Controller::GetInstance().mViewPanel;
   bool subdivOption = Controller::GetInstance().mViewPanel->mSubdivOption->value() != 0;
   if (subdivOption)
   {
      MeshView* sMesh = m->GetSubdivisionMesh();
      if (sMesh) m = sMesh;
   }
   const MeshViewConfig& config = m->GetConfig();

   view->mMeshName->copy_label(m->mName.c_str());
   view->mMeshName->redraw();

   view->mSectionList->clear();
   const std::vector<int>& regions = m->GetRegions();
   for (size_t i = 0, j = 0; i < regions.size(); ++i)
   {
      bool shown = config.mHiddenRegions.size() <= j 
                || regions[i] != config.mHiddenRegions[j];
      if (! shown)
      {
         ++j;
      }
      int r = regions[i];
      view->mSectionList->add(ColorCheckBrowser::RegionLabel(r).c_str(), shown ? 1 : 0);
   }
   view->mSectionList->redraw();

   SetWidgetValue(view->mShowAllVerts, config.mShowVerts);
   SetWidgetValue(view->mShowCreaseEdges, config.mShowCreaseEdges);
   SetWidgetValue(view->mShowCreaseFaces, config.mShowFaces);
   SetWidgetValue(view->mShowCreaseVerts, config.mShowCreaseVerts);
   SetWidgetValue(view->mShowFaceOutline, config.mOutlineFaces);
   SetWidgetValue(view->mShowPolyhedra, config.mShowPolys);
   SetWidgetValue(view->mShowPolyOutline, config.mOutlinePolys);
   SetWidgetValue(view->mFlipMaterials, config.mFlipMaterials);

   SetWidgetValue(view->mFaceAlpha, config.mFaceAlpha);
   SetWidgetValue(view->mPolyAlpha, config.mPolyAlpha);
   SetWidgetValue(view->mPolyScale, config.mPolyScale);
   if (subdivOption)
   {
      view->mShowLandmarks->hide();
   }
   else
   {
      SetWidgetValue(view->mShowLandmarks, config.mShowLandmarks);
      view->mShowLandmarks->show();
   }
   int subdivLvl = baseMeshPtr->GetSubdivision();
   SetWidgetValue(view->mSubdivisionLevel, subdivLvl);
   
}

void MenuEvents::PullMeshConfig()
{
   MeshView* m = ViewScene::GetInstance().GetSelectedMesh();
   if (!m) return;
   ViewPanel* view = Controller::GetInstance().mViewPanel;
   MeshViewConfig config = m->GetConfig();

   config.mHiddenRegions.clear();
   const std::vector<int>& regions = m->GetRegions();
   for (size_t i = 0, j = 0; i < regions.size(); ++i)
   {
      bool enabled = view->mSectionList->checked(i+1) != 0;
      if (! enabled)
      {
         config.mHiddenRegions.push_back(regions[i]);
      }
   }

   
   GetWidgetValue(view->mShowAllVerts, config.mShowVerts);
   GetWidgetValue(view->mShowCreaseEdges, config.mShowCreaseEdges);
   GetWidgetValue(view->mShowCreaseFaces, config.mShowFaces);
   GetWidgetValue(view->mShowCreaseVerts, config.mShowCreaseVerts);
   GetWidgetValue(view->mShowFaceOutline, config.mOutlineFaces);
   GetWidgetValue(view->mShowPolyhedra, config.mShowPolys);
   GetWidgetValue(view->mShowPolyOutline, config.mOutlinePolys);
   GetWidgetValue(view->mFlipMaterials, config.mFlipMaterials);

   GetWidgetValue(view->mFaceAlpha, config.mFaceAlpha);
   GetWidgetValue(view->mPolyAlpha, config.mPolyAlpha);
   GetWidgetValue(view->mPolyScale, config.mPolyScale);
   GetWidgetValue(view->mShowLandmarks, config.mShowLandmarks);

   bool subdivOption = Controller::GetInstance().mViewPanel->mSubdivOption->value() != 0;
   m->SetConfig(config, subdivOption);

   Controller::GetInstance().RedrawGl();
}